﻿using System.Collections.Generic;
using System.IO;

namespace NMock2.Internal
{
	public class ExpectationOrderingBase
	{
		/// <summary>
		/// Stores the expectations that could be added.
		/// </summary>
		protected List<IExpectation> expectations = new List<IExpectation>();

		/// <summary>
		/// Stores the calling depth for the document writer output.
		/// </summary>
		protected int depth;

		protected string prompt;

		public void AddExpectation(IExpectation expectation)
		{
			expectations.Add(expectation);
		}

		public void RemoveExpectation(IExpectation expectation)
		{
			expectations.Remove(expectation);
		}

		public void DescribeActiveExpectationsTo(TextWriter writer)
		{
			writer.WriteLine(prompt);
			foreach (IExpectation expectation in this.expectations)
			{
				if (expectation.IsActive)
				{
					Indent(writer, depth + 1);
					expectation.DescribeActiveExpectationsTo(writer);
					writer.WriteLine();
				}
			}
		}

		public void DescribeUnmetExpectationsTo(TextWriter writer)
		{
			writer.WriteLine(prompt);
			foreach (IExpectation expectation in this.expectations)
			{
				if (!expectation.HasBeenMet)
				{
					Indent(writer, depth + 1);
					expectation.DescribeUnmetExpectationsTo(writer);
					writer.WriteLine();
				}
			}
		}

		/// <summary>
		/// Adds all expectations to <paramref name="result"/> that are associated to <paramref name="mock"/>.
		/// </summary>
		/// <param name="mock">The mock for which expectations are queried.</param>
		/// <param name="result">The result to add matching expectations to.</param>
		public void QueryExpectationsBelongingTo(IMockObject mock, IList<IExpectation> result)
		{
			expectations.ForEach(expectation => expectation.QueryExpectationsBelongingTo(mock, result));
		}



		private void Indent(TextWriter writer, int n)
		{
			for (int i = 0; i < n; i++)
			{
				writer.Write("  ");
			}
		}

	}
}
